package com.bawei.lib_base.utils.utils.mvi

import android.graphics.pdf.PdfDocument.Page
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingSource
import androidx.paging.cachedIn
import com.bawei.lib_base.utils.utils.request.RequestType
import com.bawei.lib_base.utils.utils.res.Res
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import java.lang.reflect.Type
import java.text.SimpleDateFormat

abstract class BaseViewModel<UiIntent : IUiIntent> : ViewModel(){

    val channel = Channel<UiIntent>()

    private var state = MutableStateFlow<UiState>(UiState.onLoading)

    val uiState : StateFlow<UiState>
    get() = state.asStateFlow()

    init {
        viewModelScope.launch {
            channel.receiveAsFlow().collect{
                handelIntent(it)
            }
        }
    }

    //处理意图
    abstract fun handelIntent(it : UiIntent)

    //发送意图
    fun sendIntent(intent: UiIntent){
        viewModelScope.launch {
            channel.send(intent)
        }
    }

    //网络请求
    fun <T> httpRequest(request:Flow<Res<T>>,type : RequestType = RequestType.SPACE){
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO).catch {
                Log.i("===", it.message.toString())
            }.collect {
                if(it.code==200){
                    state.value=UiState.onSuccess(it.data,type)
                }else{
                    state.value=UiState.onError(it.message)
                }
            }
        }
    }

    fun <T : Any> pagingRequest(pagingSource: () -> PagingSource<Int,T>){
        val dataFlow = Pager(
            config = PagingConfig(10),
            pagingSourceFactory = pagingSource
        ).flow.cachedIn(viewModelScope)

        viewModelScope.launch {
            dataFlow.flowOn(Dispatchers.IO).catch {
                Log.i("===", it.message.toString())
            }.collect{
                state.value = UiState.onSuccess(it)
            }
        }
    }

    fun mapToBody(map : Any) : RequestBody {
        val toJson = Gson().toJson(map)
        return RequestBody.create("application/json;charset=utf-8".toMediaTypeOrNull(),toJson)
    }

    fun getDataTime(time : Long) :String{
        return SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time)
    }

    fun getTime(time: Long) : String{
        return SimpleDateFormat("HH:mm:ss").format(time)
    }

    fun getData(time: Long) : String{
        return SimpleDateFormat("yyyy-MM-dd").format(time)
    }

    fun getMonth(time: Long) : String{
        return SimpleDateFormat("yyyy-MM").format(time)
    }
}